import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'


 import * as dat from 'dat.gui';
// 导入dat.gui库

export const mixins = {
  data() {
    return {
      textureLoader: new THREE.TextureLoader(),
     
      objectss:[],
      objectReItem:null,
      roomurl: 'QXXBFXY_CJ.glb',
      cameras: null,
      scale: 0,
      XiBaoFenXiYi4:'',
    
      //鼠标放上会变成手，并且显示提示气泡
      objectNames: [
        'XiaoDuYe', //
        'XiBaoFenXiYi13_1',
        'RongXueJi1',
        'RongXueJi2',
        'RongXueJi3',
        'RongXueJi4',
        'XiBaoFenXiYi15',
        'XiBaoFenXiYi12',
        'XiBaoFenXiYi3',
        'XiBaoFenXiYi4'

      ],
      //气泡对应名称
      objectText: [ 
        { name: 'XiaoDuYe', text: '消毒液' },
        { name: 'XiBaoFenXiYi13_1', text: '废液桶' },
        { name: 'RongXueJi1', text: '所有试剂' },
        { name: 'RongXueJi2', text: 'RongXueJi2' },
        { name: 'RongXueJi3', text: 'RongXueJi3' },
        { name: 'RongXueJi4', text: 'RongXueJi4' },
        { name: 'XiBaoFenXiYi15', text: '检查管道' },
        { name: 'XiBaoFenXiYi12', text: 'XiBaoFenXiYi12' },
        { name: 'XiBaoFenXiYi3', text: '电源开关' },
        {name:'XiBaoFenXiYi4',text:'贴图屏幕'}
       
      ],
    };
  },

  created() { },
  mounted() { },
  beforeDestroy() {
  
    clearTimeout()
    try {
      this.scene.clear()
      this.render.dispose()
      this.render.forceContextLoss()
      this.render.content = null
      // cancelAnimationFrame(animationID) // 去除animationFrame
      const gl = this.render.domElement.getContext('webgl')
      gl && gl.getExtension('WEBGL_lose_context').loseContext()
    } catch (e) {
      console.log(e)
    }
  },
  watch: {
    roomurl: {
      handler(val) { 
        if (val) { 
          console.log('监听到场景变化');
          this.initFile()
        }
      },
      deep: true,
      immediate:true
    }
  },
      computed: {
    getPosition() {
      //根据返回的位置信息计算物品提示小标位
      let maincontWidth = this.$el.offsetWidth
      let maincontHeight = this.$el.offsetHeight
      let leftPercentage = ((this.tipPosition.x + 25) / maincontWidth) * 100
      let topPercentage = ((this.tipPosition.y - 30) / maincontHeight) * 100
      return 'left:' + leftPercentage + '%;top:' + topPercentage + '%;'
    }
  },
    methods: {
            //初始化
    init() { 
      this.initSence()
      this.raycaster = new THREE.Raycaster() // 设置光线拾取
      this.clock = new THREE.Clock()
      this.mouse = new THREE.Vector2()
        },
            //初始化相机
    initCeremar() {
      const camera = new THREE.PerspectiveCamera(
        50,
        window.innerWidth / window.innerHeight,
        0.01,
        10000
      )
      camera.position.set(
        this.cameraOriginal[0],
        this.cameraOriginal[1],
        this.cameraOriginal[2]
      )

      this.camera = camera;
      this.scene.add(this.camera);
      this.cameras = this.camera 
       this.move(
          [0.687, 1.490, -2.845],
          [-2.68 / 180, -0.02 / 180, 0]
        )
      // this.
    },
    //初始化场景
    initSence() {
     var scene = new THREE.Scene();
				scene.background = new THREE.Color(0xbfbfbf);
      this.scene = scene;
       this.initLight()
      this.initCeremar()
      this.initRenderer()
      this.initCotronl()
      this.initPoint()
      this.initFile()
      this.initFileS(0)
      },

    //初始化渲染器
    initRenderer() {

       this.render = new THREE.WebGLRenderer({
        antialias: true,
       
       logarithmicDepthBuffer: true
      })
      this.render.setClearColor(0xaaaaaa);
      this.render.setPixelRatio(window.devicePixelRatio*2)
       this.render.setSize(window.innerWidth, window.innerHeight)
      this.render.shadowMap.enabled = true
      this.render.shadowMap.type = THREE.PCFSoftShadowMap;
      this.render.toneMapping = THREE.ACESFilmicToneMapping;
         this.render.toneMappingExposure = 0.6
      // this.render.outputEncoding = THREE.LinearSRGBColorSpace
  
      this.render.outputColorSpace = THREE.SRGBColorSpace
      
       this.$el.appendChild(this.render.domElement)
    window.addEventListener('resize', this.onWindowResize) //监听窗口变化
      },
        //根据屏幕尺寸变化自适应
        onWindowResize() {
      //浏览器窗口大小改变后重新计算
      this.maincontWidth = this.$el.offsetWidth
      this.maincontHeight = this.$el.offsetHeight
      this.maincontSc = this.maincontWidth / this.maincontHeight
      this.camera.aspect = this.maincontSc
      this.camera.updateProjectionMatrix()
      this.render.setSize(this.maincontWidth, this.maincontHeight)
    }, //鼠标移动6+射线拾取
    //初始化控制器
    initCotronl() {
      this.mouse = new THREE.Vector2() //获取鼠标 位置二维坐标信息
      document.body.addEventListener('mousemove', this.onDocumentMouseMove)
      document.body.addEventListener('mousedown', this.onDocumentMouseDown)
      this.$el.addEventListener('mouseup', this.onDocumentMouseUp)
    }, //初始化物体
      initFile() {
      this.$emit('loadingfn', true);
      let gltfloader = new GLTFLoader()
      this.app = gltfloader
      const dracoLoader = new DRACOLoader()
      // dracoLoader.setDecoderPath('/draco/')
      dracoLoader.setDecoderPath(
        'http://zfatt.oss-cn-beijing.aliyuncs.com/threejs/draco/'
      )
      dracoLoader.preload()
      gltfloader.setDRACOLoader(dracoLoader)
        gltfloader.load(this.baseURL + this.roomurl, (gltf) => {
          if(this.objectReItem) {
            this.scene.remove(this.objectReItem.scene)
             this.objectss = []
          this.objectReItem.scene.traverse((child) => {
            if (child.material) {
              child.material.dispose()
            }
            if (child.geometry) {
              child.geometry.dispose()
            }
            child = null
          })

          this.objectReItem = null
        }
        this.model = gltf.scene
   
        gltf.scene.position.set(0, 0, 0)
       
        gltf.scene.traverse((child) => {
          if (child.isMesh) {
            // child.receiveShadow = true
            // child.castShadow = true
            child.material.emissiveMap = child.material.map
            if (this.objectNames.includes(child.name)) {
              //  console.log('存在',child.name);
              //将需要检查到的模型放到objects
              this.objectss.push(child)
            }
            // if (child.name == 'DianNao5') { 
            //   console.log('存在');
            // }
            //设置模型自发光
            // child.material.emissive = child.material.color
          }
        })
          this.scene.add(gltf.scene)
          this.objectReItem = gltf
          console.log('检查到可点击的模型1',this.objectss);
        // this.render.render(this.scene, this.camera)
        // this.$emit('loadingfn', false);  
         this.animate()
      
      }
    
        )
  
        
      },
  
     
 
      destroyOldScene() { 
        if (this.objectFather) {
          this.scene.remove(this.objectFather.scene)
          this.objectFather.scene.traverse((child) => {
            if (child.material) {
              child.material.dispose()
            }
            if (child.geometry) {
              child.geometry.dispose()
            }
            child = null
          })

          this.objectFather = null
        }
    
      },
    //根据步骤渲染物体和动画
      initFileS(index) {
        // if (this.andh) {
        //   return
        //  }
          //  this.$emit('loadingfn', true);
       
      let gltfloader = new GLTFLoader()
      const dracoLoader = new DRACOLoader()
      // dracoLoader.setDecoderPath('/draco/')
      dracoLoader.setDecoderPath(
        'http://zfatt.oss-cn-beijing.aliyuncs.com/threejs/draco/'
      )
      dracoLoader.preload()
      gltfloader.setDRACOLoader(dracoLoader)
      gltfloader.load(this.baseURL + this.dhfiles[index].url, (gltf) => {
        this.destroyOldScene()
        gltf.scene.position.set(0, 0, 0)
        this.objects = []
        gltf.scene.traverse((child) => {
          if (child.isMesh) {
            child.castShadow = false
            child.receiveShadow = true
            child.castShadow = true
            if (child.name == 'XiBaoFenXiYi4') { 
              this.XiBaoFenXiYi4 = child
              
            }
            if (this.objectNames.includes(child.name)) {
              //将需要检查到的模型放到objects
              this.objects.push(child)
             
            }
  
          
            child.material.emissiveMap = child.material.map
            // child.material.emissive = child.material.color
          }
        })
        this.scene.add(gltf.scene)
        this.objectFather = gltf
        this.andh = gltf.animations
        console.log('动画数据', gltf.animations)
        this.render.render(this.scene, this.camera)
         console.log('检查到可点击的模型',this.objects);
     
        // if (index == 2) { 
        //   this.playAction('1', 'mmfxkg')
        // }
          //  this.$emit('loadingfn', false);

        // this.initDragControls(this.Farray) //初始化拖拽控制器
      })
        },

        //初始化灯光
      initLight() {
      
     

           const ambientLight = new THREE.AmbientLight(0xffffff, 1);
      this.scene.add(ambientLight);
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1);
     
         directionalLight1.position.set(7, 0.5, -2.6);
      directionalLight1.castShadow = true;
      this.scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1);
      directionalLight2.position.set(3, 9, 2.2);
      directionalLight2.castShadow = false;
      this.scene.add(directionalLight2);
      const directionalLight3 = new THREE.DirectionalLight(0xffffff, 1);
      directionalLight3.position.set(-6.1,18, 1);
      directionalLight3.castShadow = true;
        this.scene.add(directionalLight3);

 const directionalLight4 = new THREE.DirectionalLight(0xffffff, 1);
      directionalLight4.position.set(-13.282,16.864, -24.495);

        this.scene.add(directionalLight4);
 const PointLight1 = new THREE.PointLight( 0xffffff, 1, 100 );
      PointLight1.position.set(0.467,4.833, -1.164);
        this.scene.add(PointLight1);
         const PointLight2 = new THREE.PointLight( 0xffffff, 1, 100 );
      PointLight2.position.set(12.947,5.056, -0.609);
        this.scene.add(PointLight2);
       
      // 在初始化代码中创建dat.GUI实例
const gui = new dat.GUI();

// 创建一个对象用于存储光源的位置信息
const lightControls = {
    directionalLight1X: -14.464,
    directionalLight1Y: 6.354,
    directionalLight1Z: 6.716,
    directionalLight2X: 16.085,
    directionalLight2Y: 10.375,
    directionalLight2Z: 3.257,
    directionalLight3X: -8.393,
    directionalLight3Y: 17.593,
    directionalLight3Z: 13.439
};

// 添加控制面板并定义控制项
const directionalLight1Folder = gui.addFolder('Directional Light 1');
directionalLight1Folder.add(lightControls, 'directionalLight1X', -20, 20).onChange(updateDirectionalLight1Position);
directionalLight1Folder.add(lightControls, 'directionalLight1Y', -20, 20).onChange(updateDirectionalLight1Position);
directionalLight1Folder.add(lightControls, 'directionalLight1Z', -20, 20).onChange(updateDirectionalLight1Position);

const directionalLight2Folder = gui.addFolder('Directional Light 2');
directionalLight2Folder.add(lightControls, 'directionalLight2X', -20, 20).onChange(updateDirectionalLight2Position);
directionalLight2Folder.add(lightControls, 'directionalLight2Y', -20, 20).onChange(updateDirectionalLight2Position);
directionalLight2Folder.add(lightControls, 'directionalLight2Z', -20, 20).onChange(updateDirectionalLight2Position);

const directionalLight3Folder = gui.addFolder('Directional Light 3');
directionalLight3Folder.add(lightControls, 'directionalLight3X', -20, 20).onChange(updateDirectionalLight3Position);
directionalLight3Folder.add(lightControls, 'directionalLight3Y', -20, 20).onChange(updateDirectionalLight3Position);
directionalLight3Folder.add(lightControls, 'directionalLight3Z', -20, 20).onChange(updateDirectionalLight3Position);

// 定义更新光源位置的函数
function updateDirectionalLight1Position() {
    directionalLight1.position.set(lightControls.directionalLight1X, lightControls.directionalLight1Y, lightControls.directionalLight1Z);
}

function updateDirectionalLight2Position() {
    directionalLight2.position.set(lightControls.directionalLight2X, lightControls.directionalLight2Y, lightControls.directionalLight2Z);
}

function updateDirectionalLight3Position() {
    directionalLight3.position.set(lightControls.directionalLight3X, lightControls.directionalLight3Y, lightControls.directionalLight3Z);
}

  
    },
    initPoint() {
      //初始换加载箭头指示图标
      const spriteImageLabel = (image) => {
        let textureLoader = new THREE.TextureLoader()
        const imageTexture = textureLoader.load(image)
        return imageTexture
      }
      let imgUrl = require('@/images/pointer.png')
      const spriteMap = spriteImageLabel(imgUrl)
      const spriteMaterial = new THREE.SpriteMaterial({
        map: spriteMap,
        color: 0xffffff
      })
      const sprite = new THREE.Sprite(spriteMaterial)
      sprite.scale.set(0.1, 0.1, 0.1)
      sprite.rotation.set(0, 0, Math.PI * 0.6)
      sprite.visible = false
      this.sprite = sprite
      this.scene.add(sprite)
        },
        //根据按钮播发动画
      playAction(animationName, realName) {
        console.log('播放了动画名称',animationName,'点击的物体',realName);
      this.playIng = true
      const theMixer = new THREE.AnimationMixer(this.objectFather.scene) //动画的物体
      const clip = THREE.AnimationClip.findByName(
        this.objectFather.animations,
        animationName
        ) //要播放的动画名称
          console.log('正在播放',animationName,'点击的物体',realName,clip);
      const action = theMixer.clipAction(clip)
      action.loop = THREE.LoopOnce //动画只执行一次
      action.clampWhenFinished = true //播放完成之后自动结束
        action.play()
      
      this.action = action
      theMixer.addEventListener('finished', () => {
        return setTimeout(() => {
          this.playIng = false
          this.$emit('clickItem', realName)
           console.log('动画播放完成')
        }, 600)
      })
      this.theMixer = theMixer
        },
     //循环渲染
    animate() {
      //镜头移动相关
     
      requestAnimationFrame(this.animate)
      this.render.render(this.scene, this.camera)

    
      if (this.theMixer) {
        //动画渲染  3000 控制动画没一帧之间的时长
        this.theMixer.update(this.clock.getDelta())
        // this.clock.getDelta()
      }
      //清空原本动画事件，回调animate方法
      if (this.outLineAnimationFrameID) {
        window.cancelAnimationFrame(this.outLineAnimationFrameID)
      }
      this.outLineAnimationFrameID = requestAnimationFrame(this.animate)
        },
     // 漫游代码

  
    stopAndReleaseAnimations() {
      if (this.andh && this.andh.length > 0) {
    
    this.theMixer.stopAllAction();
    this.theMixer.uncacheAction(this.action);
    // 停止动画
    this.andh.forEach((animation) => {
      animation.stop();
    });

    // 清空动画数组
    this.andh = [];

    // 释放资源
    this.renderer.dispose(); // 如果使用WebGLRenderer，可以释放Renderer的资源
    this.objects.forEach((object) => {
      if (object.geometry) {
        object.geometry.dispose();
      }
      if (object.material) {
        object.material.dispose();
      }
    });
    this.objects = [];

    // 其他可能的资源释放逻辑

    console.log('当前播放的动画已停止并释放资源');
  }
}
    }
};